package com.jianbing.dao;

import com.alibaba.fastjson.JSONObject;
import com.jianbing.entity.City;
import com.jianbing.entity.Page;
import com.jianbing.entity.SheBaoLoginTimeCount;
import com.jianbing.entity.ShebaoYanzhengmaTask;
import com.jianbing.exception.ServiceException;
import com.jianbing.mongo.MongoConnections;
import com.jianbing.mongo.MongoHelper;
import com.jianbing.util.*;
import com.mongodb.BasicDBObject;
import com.mongodb.Block;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.springframework.stereotype.Service;

import java.util.*;

import static java.util.Arrays.asList;

/**
 * Created by Han, Tixiang on 2016/9/20 0020.
 */
@Service
public class MongoDBDao {
    private static Log log = LogFactory.getLog(MongoDBDao.class);
    public static String DEFAULT_DB = PropertiesUtils.getProperties(JianbingConstants.mongoDB_DEFAULT_DB);

    /**
     * 插入数据
     *
     * @param tableName
     * @throws ServiceException
     */
    public static int getNextId(String tableName, String id) throws ServiceException {
        try {
            MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(TableUtils.getIdsTableName());
            BasicDBObject bsonUpdate = new BasicDBObject().append("$inc", new BasicDBObject().append(id, 1));
            Bson queryBson = Filters.eq("tableName", tableName);
            FindOneAndUpdateOptions options = new FindOneAndUpdateOptions();
            options.returnDocument(ReturnDocument.AFTER);
            Document object = (Document) collection.findOneAndUpdate(queryBson, bsonUpdate, options);

            if (object == null) {
                tableName = StringPoolUtils.getPoolString(tableName);
                synchronized (tableName) {
                    if (object == null) {
                        Document document = new Document();
                        document.put("tableName", tableName);
                        document.put(id, 0);
                        collection.insertOne(document);
                        object = (Document) collection.findOneAndUpdate(queryBson, bsonUpdate, options);
                    }
                }
            }
            Object obj = object.get(id);
            if (obj instanceof Integer) {
                return (Integer) obj;
            } else if (obj instanceof Number) {
                return ((Number) obj).intValue();
            } else if (obj instanceof String) {
                throw new ServiceException("invald return value" + obj);
            }

        } catch (Exception e) {
            log.error(e.toString(), e);
            throw new ServiceException(e);
        }
        return -1;
    }
    public static Object addAndUpdateById(String tableName, Object id, String updateColumn) {
        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
        BasicDBObject bsonUpdate = new BasicDBObject().append("$inc", new BasicDBObject().append(updateColumn, 1));
        Bson queryBson = Filters.eq("id", id);
        FindOneAndUpdateOptions options = new FindOneAndUpdateOptions();
        options.returnDocument(ReturnDocument.AFTER);
        Document object = (Document) collection.findOneAndUpdate(queryBson, bsonUpdate, options);
        return object.get(updateColumn).toString();
    }
    public static Object addAndUpdate(String tableName, Map<String, Object> queryParam, String updateColumn) {
        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
        BasicDBObject bsonUpdate = new BasicDBObject().append("$inc", new BasicDBObject().append(updateColumn, 1));

        if (queryParam == null || queryParam.size() == 0) {
            return 0;
        }
        Bson[] bsonParamArray = new Bson[queryParam.size()];
        int i = 0;
        for (Map.Entry<String, Object> entry : queryParam.entrySet()) {
            Bson bson = Filters.eq(entry.getKey(), entry.getValue());
            bsonParamArray[i++] = bson;
        }

        Bson queryBson = Filters.and(bsonParamArray);
        FindOneAndUpdateOptions options = new FindOneAndUpdateOptions();
        options.returnDocument(ReturnDocument.AFTER);
        Document object = (Document) collection.findOneAndUpdate(queryBson, bsonUpdate, options);

        return object.get(updateColumn).toString();
    }

    public static void main(String[] args) throws ServiceException {
       /* Map parameterMap = new HashMap();
        parameterMap.put("state", TaskHelper.NEW);
        Map sortMap = new HashMap();
        sortMap.put("createDate", -1);
        List<Integer> list = new ArrayList<>();
        list.add(11);
        list.add(12);
        List<ShebaoYanzhengmaTask> resultList = MongoDBDao.queryTaskForList(TableUtils.getTableName(ShebaoYanzhengmaTask.class), null, sortMap, ShebaoYanzhengmaTask.class, null, null, -1, -1, null, true);
        System.out.println(resultList);

        Map map = new HashMap<>();
        map.put("state", 12222);
        List<City> citys = MongoDBDao.queryForList(TableUtils.getTableName(City.class), map, City.class);
        System.out.println(citys);*/
        Map map = new HashMap();
        map.put("_id", new ObjectId("58848d032f59040ecd5982ab"));
        Object a = addAndUpdate("test_ip", map, "port");

        Map<String, Object> queryParam = new HashMap<String, Object>();
        queryParam.put("loginParamId", "58848d032f59040ecd5982ab");
        SheBaoLoginTimeCount sheBaoLoginTimeCount = MongoDBDao.findOneByMap(TableUtils.getTableName(SheBaoLoginTimeCount.class), queryParam, SheBaoLoginTimeCount.class);
        System.out.println(sheBaoLoginTimeCount);
    }

    public static void insert(String tableName, Object object) throws ServiceException {
        if (StringUtils.isEmpty(tableName) || object == null) {
            return;
        }
        try {
            long l = System.currentTimeMillis();
            Document document = MongoHelper.bean2Document(object);
            document.put("_id", getNextId(tableName, "__id"));
            insert(tableName, document);
        } catch (Exception e) {
            log.error(e.toString(), e);
            throw new ServiceException("insert fail", e);
        }
    }


    public static void insert(String tableName, Document document) throws ServiceException {
        if (StringUtils.isEmpty(tableName) || document == null) {
            return;
        }
        try {
            MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName).insertOne(document);
        } catch (Exception e) {
            log.error(e.toString(), e);
            throw new ServiceException("insert fail", e);
        }
    }

    /**
     * 删除数据
     *
     * @param tableName
     * @param params
     * @return
     * @throws IllegalAccessException
     */
    public static long delete(String tableName, Map<String, String> params) throws ServiceException {
        if (params == null || params.size() == 0) {
            return 0;
        }

        Bson[] bsonParamArray = new Bson[params.size()];
        int i = 0;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            Bson bson = Filters.eq(entry.getKey(), entry.getValue());
            bsonParamArray[i++] = bson;
        }

        DeleteResult result = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName).deleteMany(Filters.and(bsonParamArray));
        if (result != null) {
            return result.getDeletedCount();
        }
        return 0;
    }

    public static long deleteByIds(String tableName, List<Object> ids) throws ServiceException {
        if (ids == null || ids.size() == 0) {
            return 0;
        }

        DeleteResult result = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName).deleteMany(Filters.in("id", ids.toArray()));

        if (result != null) {
            return result.getDeletedCount();
        }
        return 0;
    }

    public static long delete(String tableName, String idName, Object id) throws ServiceException {
        if (StringUtils.isEmpty(tableName) || id == null) {
            return 0;
        }

        BasicDBObject object = new BasicDBObject(idName, id);
        if ("_id".equals(idName)) {
            object = new BasicDBObject(idName, new ObjectId(id.toString()));
        }
        DeleteResult result = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName).deleteOne(object);
        if (result != null) {
            return result.getDeletedCount();
        }
        return 0;
    }

    /**
     * 删除数据
     *
     * @param tableName
     * @return
     * @throws IllegalAccessException
     */
    public static long delete(String tableName, Object id) throws ServiceException {
        if (StringUtils.isEmpty(tableName) || id == null) {
            return 0;
        }

        DeleteResult result = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName).deleteOne(new BasicDBObject("id", id));
        if (result != null) {
            return result.getDeletedCount();
        }
        return 0;
    }

    public static long update(String tableName, String idName, Object id, Document document) throws ServiceException {
        if (StringUtils.isEmpty(tableName) || id == null || document == null) {
            return 0;
        }
        try {
            MongoCollection<Document> connection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
            Bson object = null;
            if ("_id".equals(idName)) {
                object = Filters.eq("_id", new ObjectId(id.toString()));
            } else if ("id".equals(idName)) {
                object = Filters.eq("id", id);
            }
            UpdateResult result = connection.updateOne(object, new Document("$set", document));
            if (result != null) {
                log.info("update success, record num: " + result.getMatchedCount());
                return result.getMatchedCount();
            } else
                return 0;
        } catch (Exception e) {
            log.error(e.toString(), e);
            throw new ServiceException("update fail", e);
        }
    }

    public static long update(String tableName, Object object, Object id) throws ServiceException {
        if (StringUtils.isEmpty(tableName) || id == null || object == null) {
            return 0;
        }
        try {
            MongoCollection<Document> connection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
            Bson bson = Filters.eq("id", id);
            UpdateResult result = connection.updateOne(bson, new Document("$set", MongoHelper.bean2Document(object)));
            if (result != null) {
                log.info("update success, record num: " + result.getMatchedCount());
                return result.getMatchedCount();
            } else
                return 0;
        } catch (Exception e) {
            log.error(e.toString(), e);
            throw new ServiceException("update fail", e);
        }
    }

    /**
     * 更新数据
     *
     * @param tableName
     * @param object
     * @param keyParameters
     * @return
     * @throws ServiceException
     */

    public static long update(String tableName, Object object, Map<String, String> keyParameters) throws ServiceException {
        try {
            if (keyParameters == null || keyParameters.size() == 0) {
                return 0;
            }

            Bson[] bsonParamArray = new Bson[keyParameters.size()];
            int i = 0;
            for (Map.Entry<String, String> entry : keyParameters.entrySet()) {
                Bson bson = Filters.eq(entry.getKey(), entry.getValue());
                bsonParamArray[i++] = bson;
            }

            MongoCollection<Document> connection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
            UpdateResult result = connection.updateMany(Filters.and(bsonParamArray), new Document("$set", MongoHelper.bean2Document(object)));
            if (result != null) {
                return result.getMatchedCount();
            } else
                return 0;
        } catch (Exception e) {
            log.error(e.toString(), e);
            throw new ServiceException("update fail", e);
        }
    }

    public static Document findOne(String tableName, Map<String, String> keyParams) throws ServiceException {
        if (keyParams == null || keyParams.size() == 0) {
            return null;
        }
        Bson[] bsonParamArray = new Bson[keyParams.size()];
        int i = 0;
        for (Map.Entry<String, String> entry : keyParams.entrySet()) {
            Bson bson = Filters.eq(entry.getKey(), entry.getValue());
            bsonParamArray[i++] = bson;
        }
        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
        Document document = (Document) collection.find(Filters.and(bsonParamArray)).first();
        return document;
    }

    public static <T> T findOne(String tableName, String idName, String id, Class<T> returnClass) throws ServiceException {
        if (StringUtils.isEmpty(tableName) || id == null) {
            return null;
        }
        Bson bson = Filters.eq(idName, id);
        if ("_id".equals(idName)) {
            bson = Filters.eq(idName, new ObjectId(id));
        }
        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
        Document document = (Document) collection.find(bson).first();
        return MongoHelper.document2Bean(document, returnClass);
    }

    public static <T> T findOne(String tableName, Object id, Class<T> returnClass) throws ServiceException {
        if (StringUtils.isEmpty(tableName) || id == null) {
            return null;
        }

        Bson bson = Filters.eq("id", id);
        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
        Document document = (Document) collection.find(bson).first();
        return MongoHelper.document2Bean(document, returnClass);
    }


    public static <T> T findOneByMap(String tableName, Map<String, Object> keyParams, Class<T> returnClass) throws ServiceException {
        if (keyParams == null || keyParams.size() == 0) {
            return null;
        }
        Bson[] bsonParamArray = new Bson[keyParams.size()];
        int i = 0;
        for (Map.Entry<String, Object> entry : keyParams.entrySet()) {
            Bson bson = Filters.eq(entry.getKey(), entry.getValue());
            bsonParamArray[i++] = bson;
        }
        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
        Document document = (Document) collection.find(Filters.and(bsonParamArray)).first();
        return MongoHelper.document2Bean(document, returnClass);
    }

    public static List<JSONObject> groupByState(String tableName, Map<String, String> params, Date startDate, Date endDate) throws ServiceException {
        return countGroupBy(tableName, params, startDate, endDate, "state");
    }

    public static List<Integer> maxGroupBy(String tableName, Map<String, String> params, Date startDate, Date endDate, final String... groups) throws ServiceException {
        try {
            MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
            List<Document> parameterLists = new ArrayList<Document>();
            if (params != null && params.size() > 0) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    parameterLists.add(new Document(entry.getKey(), entry.getValue()));
                }
            }

            if (startDate != null) {
                parameterLists.add(new Document("createDate", new Document("$gte", startDate)));
            }

            if (endDate != null) {
                parameterLists.add(new Document("createDate", new Document("$lte", endDate)));
            }
            Document timestampRange = new Document();
            if (parameterLists.size() > 0) {
                timestampRange = new Document("$and", parameterLists);
            }
            Document groupDocument = null;
            if (groups != null && groups.length > 0) {
                groupDocument = new Document();
                for (int i = 0; i < groups.length; i++) {
                    groupDocument.append(groups[i], "$" + groups[i]);
                }
            }
            AggregateIterable<Document> iterable = collection.aggregate(asList(
                    new Document("$match", timestampRange),
                    new Document("$group", new Document("_id", groupDocument).append("maxId", new Document("$max", "$id")))
            ));

            final List list = new ArrayList();
            iterable.forEach(new Block<Document>() {
                @Override
                public void apply(final Document document) {
                    list.add(Integer.valueOf(document.get("maxId").toString()));
                }
            });
            return list;
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return null;
    }

    public static List<JSONObject> countGroupBy(String tableName, Map<String, String> params, Date startDate, Date endDate, final String... groups) throws ServiceException {
        try {
            MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
            List<Document> parameterLists = new ArrayList<Document>();
            if (params != null && params.size() > 0) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    parameterLists.add(new Document(entry.getKey(), entry.getValue()));
                }
            }

            if (startDate != null) {
                parameterLists.add(new Document("createDate", new Document("$gte", startDate)));
            }

            if (endDate != null) {
                parameterLists.add(new Document("createDate", new Document("$lte", endDate)));
            }
            Document timestampRange = new Document();
            if (parameterLists.size() > 0) {
                timestampRange = new Document("$and", parameterLists);
            }
            Document groupDocument = null;
            if (groups != null && groups.length > 0) {
                groupDocument = new Document();
                for (int i = 0; i < groups.length; i++) {
                    groupDocument.append(groups[i], "$" + groups[i]);
                }
            }
            AggregateIterable<Document> iterable = collection.aggregate(asList(
                    new Document("$match", timestampRange),
                    new Document("$group", new Document("_id", groupDocument).append("count", new Document("$sum", 1)))
            ));

            final List list = new ArrayList();
            iterable.forEach(new Block<Document>() {
                @Override
                public void apply(final Document document) {
                    Document documentkey = (Document) document.get("_id");
                    JSONObject jsonObj = new JSONObject();
                    if (groups != null && groups.length > 0) {
                        for (String group : groups) {
                            jsonObj.put(group, documentkey.get(group));
                        }
                    }
                    jsonObj.put("count", document.get("count"));

                    list.add(jsonObj);
                }
            });
            return list;
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return null;
    }

    public static <T> int count(String tableName, Map<String, String> params, List<Integer> cityIds, Date startDate, Date endDate) {
        try {
            MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
            List<Document> parameterLists = new ArrayList<Document>();
            if (params != null && params.size() > 0) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    parameterLists.add(new Document(entry.getKey(), entry.getValue()));
                }
            }

            if (ColletionUtils.isNotEmpty(cityIds)) {
                parameterLists.add(new Document("cityId", new Document("$in", cityIds)));
            }
            if (startDate != null) {
                parameterLists.add(new Document("createDate", new Document("$gte", startDate)));
            }

            if (endDate != null) {
                parameterLists.add(new Document("createDate", new Document("$lte", endDate)));
            }

            Document timestampRange = new Document();
            if (parameterLists.size() > 0) {
                timestampRange = new Document("$and", parameterLists);
            }
            AggregateIterable<Document> iterable = collection.aggregate(asList(
                    new Document("$match", timestampRange),
                    new Document("$group", new Document("_id", null).append("count", new Document("$sum", 1)))
            ));
            Document document = iterable.first();
            if (document == null) return -1;
            return (Integer) document.get("count");
        } catch (Exception e) {
            log.error(e.toString(), e);
            return 0;
        }
    }

    public static <T> int count(String tableName, Map<String, String> params, Date startDate, Date endDate) {
        try {
            MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
            List<Document> parameterLists = new ArrayList<Document>();
            if (params != null && params.size() > 0) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    parameterLists.add(new Document(entry.getKey(), entry.getValue()));
                }
            }

            if (startDate != null) {
                parameterLists.add(new Document("createDate", new Document("$gte", startDate)));
            }

            if (endDate != null) {
                parameterLists.add(new Document("createDate", new Document("$lte", endDate)));
            }

            Document timestampRange = new Document();
            if (parameterLists.size() > 0) {
                timestampRange = new Document("$and", parameterLists);
            }
            AggregateIterable<Document> iterable = collection.aggregate(asList(
                    new Document("$match", timestampRange),
                    new Document("$group", new Document("_id", null).append("count", new Document("$sum", 1)))
            ));
            Document document = iterable.first();
            if (document == null) return -1;
            return (Integer) document.get("count");
        } catch (Exception e) {
            log.error(e.toString(), e);
            return 0;
        }
    }

    public static <T> Page<T> queryForPage(String tableName, Map<String, String> params, Map<String, Integer> sorts, Class<T> returnType, Date startDate, Date endDate, int currentPage, int pageSize) {
        Page<T> page = new Page<T>();
        page.setTotalRecords(count(tableName, params, startDate, endDate));
        if (page.getTotalRecords() <= 0) return page;
        if (currentPage > 0) {
            page.setCurrentPage(currentPage);
        }
        if (pageSize > 0) {
            page.setPageSize(pageSize);
        }
        List<T> list = queryForList(tableName, params, sorts, returnType, startDate, endDate, (page.getCurrentPage() - 1) * page.getPageSize(), page.getPageSize());
        page.setList(list);
        return page;
    }

    public static <T> List<T> queryForList(String tableName, Map<String, String> params, Class<T> returnType) {
        return queryForList(tableName, params, null, returnType, null, null, null, null);
    }


    public static <T> List<T> queryTaskForList(String tableName, Map<String, String> params, Map<String, Integer> sortParameters, final Class<T> returnType, Date startDate, Date endDate, Integer skipSize, Integer limitNumber, List<Integer> cityIds, boolean scriptError) {
        if (StringUtils.isEmpty(tableName))
            return null;

        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);

        final List<T> list = new ArrayList<T>();
        int size = 0;

        if (params != null) {
            size = params.size();
        }

        if (startDate != null) {
            size++;
        }
        if (endDate != null) {
            size++;
        }

        if (scriptError) {
            size++;
        }

        if (ColletionUtils.isNotEmpty(cityIds)) {
            size++;
        }
        Bson[] bsonParamArray = new Bson[size];
        int i = 0;
        Bson bson = null;

        if (params != null && params.size() > 0) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                bson = Filters.eq(entry.getKey(), entry.getValue());
                bsonParamArray[i++] = bson;
            }
        }
        if (ColletionUtils.isNotEmpty(cityIds)) {
            bsonParamArray[i++] = Filters.in("cityId", cityIds);
        }
        if (startDate != null) {
            bson = Filters.gte("createDate", startDate);
            bsonParamArray[i++] = bson;
        }

        if (endDate != null) {
            bson = Filters.lte("createDate", endDate);
            bsonParamArray[i++] = bson;
        }

        if (scriptError) {
            String patten = "查询失败|数据解析失败";
            log.error(patten);
            bsonParamArray[i++] = Filters.regex("note", patten);
        }

        Block<Document> processList = new Block<Document>() {
            @Override
            public void apply(final Document document) {
                try {
                    list.add(MongoHelper.document2Bean(document, returnType));
                } catch (Exception e) {
                }
            }
        };
        Document sortDocument = new Document();
        if (sortParameters != null) {
            for (Map.Entry<String, Integer> sort : sortParameters.entrySet()) {
                sortDocument.append(sort.getKey(), sort.getValue());
            }
        }
        FindIterable<Document> findIterable = null;

        if (bsonParamArray != null && bsonParamArray.length > 0) {
            findIterable = collection.find(Filters.and(bsonParamArray));
        } else {
            findIterable = collection.find();
        }
        findIterable = findIterable.sort(sortDocument);
        if (skipSize != null && skipSize > 0) {
            findIterable = findIterable.skip(skipSize);
        }
        if (limitNumber != null && limitNumber > 0) {
            findIterable = findIterable.limit(limitNumber);
        }
        findIterable.forEach(processList);
        return list;
    }


    public static <T> List<T> queryForList(String tableName, Map<String, String> params, Map<String, Integer> sortParameters, final Class<T> returnType, String dateColumn, Date startDate, Date endDate, Integer skipSize, Integer limitNumber) {
        if (StringUtils.isEmpty(tableName))
            return null;

        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);

        final List<T> list = new ArrayList<T>();
        int size = 0;

        if (params != null) {
            size = params.size();
        }

        if (startDate != null) {
            size++;
        }
        if (endDate != null) {
            size++;
        }
        Bson[] bsonParamArray = new Bson[size];
        int i = 0;
        Bson bson = null;

        if (params != null && params.size() > 0) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                bson = Filters.eq(entry.getKey(), entry.getValue());
                bsonParamArray[i++] = bson;
            }
        }

        if (startDate != null && StringUtils.isNotEmpty(dateColumn)) {
            bson = Filters.gte(dateColumn, startDate);
            bsonParamArray[i++] = bson;
        }

        if (endDate != null && StringUtils.isNotEmpty(dateColumn)) {
            bson = Filters.lte(dateColumn, endDate);
            bsonParamArray[i++] = bson;
        }

        Block<Document> processList = new Block<Document>() {
            @Override
            public void apply(final Document document) {
                try {
                    list.add(MongoHelper.document2Bean(document, returnType));
                } catch (Exception e) {
                }
            }
        };
        Document sortDocument = new Document();
        if (sortParameters != null) {
            for (Map.Entry<String, Integer> sort : sortParameters.entrySet()) {
                sortDocument.append(sort.getKey(), sort.getValue());
            }
        }
        FindIterable<Document> findIterable = null;

        if (bsonParamArray != null && bsonParamArray.length > 0) {
            findIterable = collection.find(Filters.and(bsonParamArray));
        } else {
            findIterable = collection.find();
        }
        findIterable = findIterable.sort(sortDocument);
        if (skipSize != null && skipSize > 0) {
            findIterable = findIterable.skip(skipSize);
        }
        if (limitNumber != null && limitNumber > 0) {
            findIterable = findIterable.limit(limitNumber);
        }
        findIterable.forEach(processList);
        return list;
    }

    public static <T> List<T> queryForList(String tableName, Map<String, String> params, Map<String, Integer> sortParameters, final Class<T> returnType, Date startDate, Date endDate, Integer skipSize, Integer limitNumber) {
        return queryForList(tableName, params, sortParameters, returnType, "createDate", startDate, endDate, skipSize, limitNumber);
       /* if (StringUtils.isEmpty(tableName))
            return null;

        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);

        final List<T> list = new ArrayList<T>();
        int size = 0;

        if (params != null) {
            size = params.size();
        }

        if (startDate != null) {
            size++;
        }
        if (endDate != null) {
            size++;
        }
        Bson[] bsonParamArray = new Bson[size];
        int i = 0;
        Bson bson = null;

        if (params != null && params.size() > 0) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                bson = Filters.eq(entry.getKey(), entry.getValue());
                bsonParamArray[i++] = bson;
            }
        }

        if (startDate != null) {
            bson = Filters.gte("createDate", startDate);
            bsonParamArray[i++] = bson;
        }

        if (endDate != null) {
            bson = Filters.lte("createDate", endDate);
            bsonParamArray[i++] = bson;
        }

        Block<Document> processList = new Block<Document>() {
            @Override
            public void apply(final Document document) {
                try {
                    list.add(MongoHelper.document2Bean(document, returnType));
                } catch (Exception e) {
                }
            }
        };
        Document sortDocument = new Document();
        if (sortParameters != null) {
            for (Map.Entry<String, Integer> sort : sortParameters.entrySet()) {
                sortDocument.append(sort.getKey(), sort.getValue());
            }
        }
        FindIterable<Document> findIterable = null;

        if (bsonParamArray != null && bsonParamArray.length > 0) {
            findIterable = collection.find(Filters.and(bsonParamArray));
        } else {
            findIterable = collection.find();
        }
        findIterable = findIterable.sort(sortDocument);
        if (skipSize != null && skipSize > 0) {
            findIterable = findIterable.skip(skipSize);
        }
        if (limitNumber != null && limitNumber > 0) {
            findIterable = findIterable.limit(limitNumber);
        }
        findIterable.forEach(processList);
        return list;*/
    }

    public static <T> List<T> queryForListByIds(String tableName, List<Integer> ids, Class<T> returnType) {


        if (StringUtils.isEmpty(tableName))
            return null;

        List<T> list = new ArrayList<T>();
        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);

        Block<Document> processList = new Block<Document>() {
            @Override
            public void apply(final Document document) {
                try {
                    list.add(MongoHelper.document2Bean(document, returnType));
                } catch (Exception e) {
                    log.error(e.toString(), e);
                }
            }
        };

        FindIterable<Document> findIterable = null;
        findIterable = collection.find(Filters.in("id", ids));


        findIterable.forEach(processList);
        return list;
    }

    public static List<Document> findAll(String tableName) {
        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
        final List<Document> list = new ArrayList<Document>();
        Block<Document> processList = new Block<Document>() {
            @Override
            public void apply(final Document document) {
                try {
                    list.add(document);
                } catch (Exception e) {
                    log.error(e.toString(), e);
                }
            }
        };
        collection.find().forEach(processList);
        return list;
    }

    public static <T> List<T> findAll(String tableName, final Class<T> clazz) {
        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName);
        final List<T> list = new ArrayList<T>();
        Block<Document> processList = new Block<Document>() {
            @Override
            public void apply(final Document document) {
                try {
                    list.add(MongoHelper.document2Bean(document, clazz));
                } catch (Exception e) {
                    log.error(e.toString(), e);
                }
            }
        };
        collection.find().forEach(processList);
        return list;
    }

    public static long deleteIPTableEndDateLess2Minutes(String tableName, Date endDate) {
        if (endDate == null) return 0;
        Bson bson = Filters.lte("expireDate", endDate);
        DeleteResult result = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName).deleteMany(bson);
        if (result != null) {
            return result.getDeletedCount();
        }
        return 0;
    }

    public static void dropCollection(String collectionName) {
        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(collectionName);
        if (collection != null) {
            collection.drop();
            log.error("删除成功");
        }
    }

    public static MongoCollection getCollection(String collectionName) {
        MongoCollection collection = MongoConnections.getDatabase(DEFAULT_DB).getCollection(collectionName);
        return collection;
    }

    public static long deleteYanzhengmaDateMoreThan10Minutes(String tableName, Date date) {
        if (date == null) return 0;
        Bson bson = Filters.lte("createDate", date);
        DeleteResult result = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName).deleteMany(bson);
        if (result != null) {
            return result.getDeletedCount();
        }
        return 0;
    }

    public static long deleteCityIdisNull(String tableName) {
        Bson bson = Filters.eq("cityId", null);
        DeleteResult result = MongoConnections.getDatabase(DEFAULT_DB).getCollection(tableName).deleteMany(bson);
        if (result != null) {
            return result.getDeletedCount();
        }
        return 0;
    }
}
